Move `target_dir` to workspace
authorAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 23 Jul 2016 01:51:09 +0000 (04:51 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Sat, 23 Jul 2016 01:51:09 +0000 (04:51 +0300)
src/cargo/core/workspace.rs
src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_doc.rs
src/cargo/ops/cargo_install.rs
src/cargo/ops/cargo_package.rs
src/cargo/ops/cargo_rustc/layout.rs
src/cargo/util/config.rs

index 074c137473f6610d7818d1ae064835e1013531e2..f4a07b9234b6ecd7a7b99260de556d73da46131d 100644 (file)
@@ -6,7 +6,7 @@ use std::slice;
 use core::{Package, VirtualManifest, EitherManifest, SourceId};
 use core::{PackageIdSpec, Dependency};
 use ops;
-use util::{Config, CargoResult};
+use util::{Config, CargoResult, Filesystem};
 use util::paths;
 
 /// The core abstraction in Cargo for working with a workspace of crates.
@@ -32,6 +32,9 @@ pub struct Workspace<'cfg> {
     // `current_manifest` was found on the filesystem with `[workspace]`.
     root_manifest: Option<PathBuf>,
 
+    // Allows to override the target directory for the purposes of `cargo install`.
+    target_dir: Option<Filesystem>,
+
     // List of members in this workspace with a listing of all their manifest
     // paths. The packages themselves can be looked up through the `packages`
     // set above.
@@ -86,6 +89,7 @@ impl<'cfg> Workspace<'cfg> {
                 packages: HashMap::new(),
             },
             root_manifest: None,
+            target_dir: None,
             members: Vec::new(),
         };
         ws.root_manifest = try!(ws.find_root(manifest_path));
@@ -103,7 +107,7 @@ impl<'cfg> Workspace<'cfg> {
     ///
     /// This is currently only used in niche situations like `cargo install` or
     /// `cargo package`.
-    pub fn one(package: Package, config: &'cfg Config) -> Workspace<'cfg> {
+    pub fn one(package: Package, config: &'cfg Config, target_dir: Option<Filesystem>) -> Workspace<'cfg> {
         let mut ws = Workspace {
             config: config,
             current_manifest: package.manifest_path().to_path_buf(),
@@ -112,6 +116,7 @@ impl<'cfg> Workspace<'cfg> {
                 packages: HashMap::new(),
             },
             root_manifest: None,
+            target_dir: target_dir,
             members: Vec::new(),
         };
         {
@@ -155,6 +160,16 @@ impl<'cfg> Workspace<'cfg> {
         }.parent().unwrap()
     }
 
+    pub fn target_dir(&self) -> Filesystem {
+        if let Some(ref fs) = self.target_dir {
+            return fs.clone()
+        }
+        if let Some(fs) = self.config.target_dir() {
+            return fs.clone()
+        }
+        Filesystem::new(self.root().join("target"))
+    }
+
     /// Returns the root [replace] section of this workspace.
     ///
     /// This may be from a virtual crate or an actual crate.
index a5eba05cb7c22fc9ac55b605dbe44317647a9d38..88c8c933ad9adc4fc7786f62cf0781f4db77d4cf 100644 (file)
@@ -16,7 +16,7 @@ pub struct CleanOptions<'a> {
 
 /// Cleans the project from build artifacts.
 pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
-    let target_dir = opts.config.target_dir(&ws);
+    let target_dir = ws.target_dir();
 
     // If we have a spec, then we need to delete some packages, otherwise, just
     // remove the whole target directory and be done with it!
index c8a8b4719a2e4a9a9fa5ed456fee483123eeaa35..b764be1a2e99bbc8f6a02f7d9fcbb580e9798505 100644 (file)
@@ -53,7 +53,7 @@ pub fn doc(ws: &Workspace,
         // Don't bother locking here as if this is getting deleted there's
         // nothing we can do about it and otherwise if it's getting overwritten
         // then that's also ok!
-        let target_dir = options.compile_opts.config.target_dir(ws);
+        let target_dir = ws.target_dir();
         let path = target_dir.join("doc").join(&name).join("index.html");
         let path = path.into_path_unlocked();
         if fs::metadata(&path).is_ok() {
index 071bb58c8c8f3fe6a7273858cd78fe8039bbdcde..093e95944446cbca649ec05ac3867791c3d0e2b6 100644 (file)
@@ -76,7 +76,20 @@ pub fn install(root: Option<&str>,
                                             crates.io, or use --path or --git to \
                                             specify alternate source"))))
     };
-    let ws = Workspace::one(pkg, config);
+
+
+    let mut td_opt = None;
+    let overidden_target_dir = if source_id.is_path() {
+        None
+    } else if let Ok(td) = TempDir::new("cargo-install") {
+        let p = td.path().to_owned();
+        td_opt = Some(td);
+        Some(Filesystem::new(p))
+    } else {
+        Some(Filesystem::new(config.cwd().join("target-install")))
+    };
+
+    let ws = Workspace::one(pkg, config, overidden_target_dir);
     let pkg = try!(ws.current());
 
     // Preflight checks to check up front whether we'll overwrite something.
@@ -89,19 +102,6 @@ pub fn install(root: Option<&str>,
         try!(check_overwrites(&dst, pkg, &opts.filter, &list, force));
     }
 
-    let mut td_opt = None;
-    let target_dir = if source_id.is_path() {
-        config.target_dir(&ws)
-    } else {
-        if let Ok(td) = TempDir::new("cargo-install") {
-            let p = td.path().to_owned();
-            td_opt = Some(td);
-            Filesystem::new(p)
-        } else {
-            Filesystem::new(config.cwd().join("target-install"))
-        }
-    };
-    config.set_target_dir(target_dir.clone());
     let compile = try!(ops::compile_ws(&ws, Some(source), opts).chain_error(|| {
         if let Some(td) = td_opt.take() {
             // preserve the temporary directory, so the user can inspect it
@@ -109,7 +109,7 @@ pub fn install(root: Option<&str>,
         }
 
         human(format!("failed to compile `{}`, intermediate artifacts can be \
-                       found at `{}`", pkg, target_dir.display()))
+                       found at `{}`", pkg, ws.target_dir().display()))
     }));
     let binaries: Vec<(&str, &Path)> = try!(compile.binaries.iter().map(|bin| {
         let name = bin.file_name().unwrap();
@@ -224,7 +224,7 @@ pub fn install(root: Option<&str>,
     if !source_id.is_path() {
         // Don't bother grabbing a lock as we're going to blow it all away
         // anyway.
-        let target_dir = target_dir.into_path_unlocked();
+        let target_dir = ws.target_dir().into_path_unlocked();
         try!(fs::remove_dir_all(&target_dir));
     }
 
index c22f44cd6ee0bd208f8a6fa72e53fe2657160b1c..f2a90a145a0a26a15ee76ded2f201e4f93d2bbbc 100644 (file)
@@ -52,7 +52,7 @@ pub fn package(ws: &Workspace,
     }
 
     let filename = format!("{}-{}.crate", pkg.name(), pkg.version());
-    let dir = config.target_dir(ws).join("package");
+    let dir = ws.target_dir().join("package");
     let mut dst = {
         let tmp = format!(".{}", filename);
         try!(dir.open_rw(&tmp, config, "package scratch space"))
@@ -266,7 +266,7 @@ fn run_verify(ws: &Workspace, tar: &File, opts: &PackageOpts) -> CargoResult<()>
     let new_pkg = Package::new(new_manifest, &manifest_path);
 
     // Now that we've rewritten all our path dependencies, compile it!
-    let ws = Workspace::one(new_pkg, config);
+    let ws = Workspace::one(new_pkg, config, None);
     try!(ops::compile_ws(&ws, None, &ops::CompileOptions {
         config: config,
         jobs: opts.jobs,
index a7575e7fdcec1216bfa54b5926fac58d9dfa7fad..67c2341fa799ce6bbf650ed5661ab28a6aae6bd0 100644 (file)
@@ -72,7 +72,7 @@ impl Layout {
     pub fn new(ws: &Workspace,
                triple: Option<&str>,
                dest: &str) -> CargoResult<Layout> {
-        let mut path = ws.config().target_dir(ws);
+        let mut path = ws.target_dir();
         // Flexible target specifications often point at filenames, so interpret
         // the target triple as a Path and then just use the file stem as the
         // component for the directory name.
index 16298a43ac5bf70ea38d7cb43b483c14f67be4da..32bbe72384eea9296f06813c2a8d9c476ae7d53d 100644 (file)
@@ -13,7 +13,7 @@ use std::str::FromStr;
 use rustc_serialize::{Encodable,Encoder};
 use toml;
 use core::shell::{Verbosity, ColorConfig};
-use core::{MultiShell, Workspace};
+use core::MultiShell;
 use util::{CargoResult, CargoError, ChainError, Rustc, internal, human};
 use util::{Filesystem, LazyCell};
 
@@ -28,7 +28,7 @@ pub struct Config {
     values: LazyCell<HashMap<String, ConfigValue>>,
     cwd: PathBuf,
     rustdoc: LazyCell<PathBuf>,
-    target_dir: RefCell<Option<Filesystem>>,
+    target_dir: Option<Filesystem>,
     extra_verbose: Cell<bool>,
     frozen: Cell<bool>,
     locked: Cell<bool>,
@@ -45,7 +45,7 @@ impl Config {
             cwd: cwd,
             values: LazyCell::new(),
             rustdoc: LazyCell::new(),
-            target_dir: RefCell::new(None),
+            target_dir: None,
             extra_verbose: Cell::new(false),
             frozen: Cell::new(false),
             locked: Cell::new(false),
@@ -108,14 +108,8 @@ impl Config {
 
     pub fn cwd(&self) -> &Path { &self.cwd }
 
-    pub fn target_dir(&self, ws: &Workspace) -> Filesystem {
-        self.target_dir.borrow().clone().unwrap_or_else(|| {
-            Filesystem::new(ws.root().join("target"))
-        })
-    }
-
-    pub fn set_target_dir(&self, path: Filesystem) {
-        *self.target_dir.borrow_mut() = Some(path);
+    pub fn target_dir(&self) -> Option<&Filesystem> {
+        self.target_dir.as_ref()
     }
 
     fn get(&self, key: &str) -> CargoResult<Option<ConfigValue>> {
@@ -371,10 +365,10 @@ impl Config {
 
     fn scrape_target_dir_config(&mut self) -> CargoResult<()> {
         if let Some(dir) = env::var_os("CARGO_TARGET_DIR") {
-            *self.target_dir.borrow_mut() = Some(Filesystem::new(self.cwd.join(dir)));
+            self.target_dir = Some(Filesystem::new(self.cwd.join(dir)));
         } else if let Some(val) = try!(self.get_path("build.target-dir")) {
             let val = self.cwd.join(val.val);
-            *self.target_dir.borrow_mut() = Some(Filesystem::new(val));
+            self.target_dir = Some(Filesystem::new(val));
         }
         Ok(())
     }